package com.mallcai.bigdata.ladon.datasource;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.dpl.entity.common.Datasource;
import com.mallcai.bigdata.ladon.service.system.IMailService;
import com.mallcai.bigdata.ladon.vo.BatchUpdateParam;
import com.mallcai.bigdata.ladon.vo.DataVo;
import com.mallcai.bigdata.ladon.vo.ExportParam;
import com.mallcai.bigdata.ladon.vo.QueryParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.ParameterDisposer;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.JdbcUtils;

import java.sql.ResultSet;

/**
 * Created by oneape<oneape15@163.com>
 * Created 2019-06-03 23:39.
 * Modify:
 */
@Slf4j
public abstract class AbstractJdbcHandler implements IDbHandler {

    /**
     * 执行sql语句
     *
     * @param ds         Datasource
     * @param queryParam QueryParam 查询条件
     * @return DataVo
     */
    @Override
    public DataVo executeSql(Datasource ds, QueryParam queryParam) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        if (dataSource == null) {
            throw new BusinessException("无效的数据源");
        }
        return dataSource.execSql(queryParam);
    }

    /**
     * 导出数据到用户邮箱
     *
     * @param ds           Datasource
     * @param params       ExportParam 导出条件
     * @param iMailService IMailService
     * @return int
     */
    @Override
    public int exportData2Email(Datasource ds, ExportParam params, IMailService iMailService) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        if (dataSource == null) {
            throw new BusinessException("无效的数据源");
        }
        return dataSource.exportData2Email(params, iMailService);
    }

    @Override
    public void execute(Datasource ds, QueryParam queryParam) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <T> int[][] batchUpdate(Datasource ds, BatchUpdateParam<T> batchUpdateParam) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <T> RunInfoResult<T> queryDataWithRunInfo(Datasource ds, String sql, PreparedStatementSetter pss, ResultSetExtractor<T> rse) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        if (dataSource == null) {
            throw new BusinessException("无效的数据源");
        }
        long start = System.currentTimeMillis();
        int timeElapsed;
        Exception error = null;
        T data = null;
        String[] execSql = new String[]{sql};
        try{
            PreparedStatementCreator preparedStatementCreator =  (con)->con.prepareStatement(sql);

            data =  dataSource.getNamedParameterJdbcTemplate().getJdbcTemplate().execute(preparedStatementCreator,ps->{
                ResultSet rs = null;
                try {
                    if (pss != null) {
                        pss.setValues(ps);
                    }
                    rs = ps.executeQuery();
                    execSql[0] = ps.toString();
                    return rse.extractData(rs);
                }
                finally {
                    JdbcUtils.closeResultSet(rs);
                    if (pss instanceof ParameterDisposer) {
                        ((ParameterDisposer) pss).cleanupParameters();
                    }
                }
            });
        }catch(Exception e){
            error = e;
        } finally {
            timeElapsed = Long.valueOf(System.currentTimeMillis() - start).intValue();
        }
        return new RunInfoResult<>(data, error,  extractSql(execSql[0]), timeElapsed);
    }

    private String extractSql(String sql) {
        int index = sql.indexOf(":");
        if (index > -1){
            return  sql.substring(index + 1);
        }
        return sql;
    }
}